package blue.http.internal.core.handler;


import blue.base.core.util.AssertUtil;
import blue.http.core.message.HttpRequest;
import blue.http.internal.core.handler.exception.ExceptionDispatcher;
import blue.http.internal.core.handler.parameter.ParameterDispatcher;
import blue.http.internal.core.parser.HttpMethodResult;
import blue.http.internal.core.parser.WebSocketMethodResult;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Jin Zheng
 * @since 1.0 2020-01-07
 */
public class HandlerFactory {

	private Map<Class<?>, Handler<?, ?>> handlerMap = new HashMap<>();

	private ExceptionDispatcher exceptionDispatcher = new ExceptionDispatcher();
	private ParameterDispatcher parameterDispatcher = new ParameterDispatcher();

	public HandlerFactory() {
		this.handlerMap.put(HttpMethodResult.class, new HttpHandler(parameterDispatcher));
		this.handlerMap.put(WebSocketMethodResult.class, new WebSocketHandler(parameterDispatcher));
	}

	public <T, V> V handle(T request, HandlerChain chain) {
		Class<?> clazz = chain.getHandler().getClass();
		Handler<T, V> handler = (Handler<T, V>) handlerMap.get(clazz);
		AssertUtil.notNull(handler, "Handler");

		HandlerResponse response = handler.handle(request, chain);
		if (response.getCause() != null) {
			exceptionDispatcher.handleException(response);
			if (request instanceof HttpRequest) {
				//HttpLogUtil.error((HttpRequest) request, response.getResult().toString(), response.getCause());
			}
		}
		return handler.response(response);
	}

}
